package com.ikingtech.framework.sdk.data.helper;

import com.ikingtech.framework.sdk.data.entity.SortEntity;
import com.ikingtech.framework.sdk.utils.Tools;

import java.util.List;
import java.util.function.BiFunction;
import java.util.function.IntSupplier;
import java.util.function.Supplier;

/**
 * @author tie yan
 */
public class DragHelperBuilder<T extends SortEntity> {

    private  AbstractDragHelper<T> dragHelper;

    protected Supplier<List<T>> nodeAfterCurrent;

    protected Supplier<List<T>> nodeAfterTarget;

    protected BiFunction<Integer, Integer, List<T>> nodeBetweenCurrentAndTarget;

    public static <T extends SortEntity> DragHelperBuilder<T> builder(Supplier<List<T>> nodeAfterCurrentSupplier,
                                                                      Supplier<List<T>> nodeAfterTargetSupplier,
                                                                      BiFunction<Integer, Integer, List<T>> nodeBetweenCurrentAndTargetFunction) {
        DragHelperBuilder<T> builder = new DragHelperBuilder<>();
        builder.nodeAfterCurrent = nodeAfterCurrentSupplier;
        builder.nodeAfterTarget = nodeAfterTargetSupplier;
        builder.nodeBetweenCurrentAndTarget = nodeBetweenCurrentAndTargetFunction;
        return builder;
    }

    public static <T extends SortEntity> DragHelperBuilder<T> builder(BiFunction<Integer, Integer, List<T>> nodeBetweenCurrentAndTargetFunction) {
        DragHelperBuilder<T> builder = new DragHelperBuilder<>();
        builder.nodeBetweenCurrentAndTarget = nodeBetweenCurrentAndTargetFunction;
        return builder;
    }

    public DragHelperBuilder<T> which(String currentParentId, String targetParentId, Boolean innerDrag) {
        if (Boolean.TRUE.equals(innerDrag)) {
            this.dragHelper = new InnerDragHelper<>();
            this.dragHelper.nodeAfterCurrent = this.nodeAfterCurrent;
            return this;
        }
        if (Tools.Str.equals(currentParentId, targetParentId)) {
            this.dragHelper = new OneLevelDragHelper<>();
            this.dragHelper.nodeBetweenCurrentAndTarget = this.nodeBetweenCurrentAndTarget;
        } else {
            this.dragHelper = new LevelCrossDragHelper<>();
            this.dragHelper.nodeAfterCurrent = this.nodeAfterCurrent;
            this.dragHelper.nodeAfterTarget = this.nodeAfterTarget;
        }
        return this;
    }

    public DragHelperBuilder<T> currentNode(Supplier<T> currentNodeSupplier) {
        this.dragHelper.currentNode = currentNodeSupplier;
        return this;
    }

    public DragHelperBuilder<T> targetNode(Supplier<T> targetNodeSupplier) {
        this.dragHelper.targetNode = targetNodeSupplier;
        return this;
    }

    public DragHelperBuilder<T> maxSortOrder(IntSupplier maxSorterOrderSupplier) {
        this.dragHelper.maxSortOrder = maxSorterOrderSupplier;
        return this;
    }

    public DragHelperBuilder<T> beforeTarget(Boolean beforeTarget) {
        this.dragHelper.beforeTarget = beforeTarget;
        return this;
    }

    public DragHelper<T> build() {
        return this.dragHelper;
    }
}
